package com.wsoft.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wsoft.core.exception.Asserts;
import com.wsoft.dto.CodeRulesDto;
import com.wsoft.entity.TsCodeRulesDataEntity;
import com.wsoft.entity.TsCodeRulesEntity;
import com.wsoft.enums.RulesTypeEnum;
import com.wsoft.manager.TsCodeRulesDataManager;
import com.wsoft.manager.TsCodeRulesManager;
import com.wsoft.mapper.TsCodeRulesMapper;
import com.wsoft.query.rules.CodeRulesBaseQuery;
import com.wsoft.query.rules.CodeRulesInsertQuery;
import com.wsoft.query.rules.CodeRulesListQuery;
import com.wsoft.query.rules.CodeRulesUpdateQuery;
import com.wsoft.service.ITsCodeRulesService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 编码规则表 服务实现类
 * </p>
 *
 * @author z001
 * @since 2024年10月16日 13:05:39
 */
@Service
public class TsCodeRulesServiceImpl extends ServiceImpl<TsCodeRulesMapper, TsCodeRulesEntity> implements ITsCodeRulesService {

    @Resource
    private TsCodeRulesManager codeRulesManager;
    @Resource
    private TsCodeRulesDataManager codeRulesDataManager;

    /**
     * 创建规则
     *
     * @param query
     * @return
     */
    @Override
    public boolean insertCodeRulers(CodeRulesInsertQuery query) {
        //校验code
        validateRulesCode(query);

        TsCodeRulesEntity entity = Convert.convert(TsCodeRulesEntity.class, query);
        entity.setVersion(1);
        return codeRulesManager.save(entity);
    }

    /**
     * 修改规则
     *
     * @param query
     * @return
     */
    @Override
    public boolean updateCodeRulers(CodeRulesUpdateQuery query) {
        TsCodeRulesEntity rulesEntity = codeRulesManager.getById(query.getId());
        //校验code 是否已经生成
        if (!rulesEntity.getCode().equals(query.getCode())
                && checkIsCreateCode(rulesEntity.getCode())) {
            //该编码已经生成code,不能修改
            Asserts.fail("[ts.code.is.create]");
        }
        //校验code
        validateRulesCode(query);
        //修改version
        int version = updateVersion(rulesEntity, query);
        rulesEntity = Convert.convert(TsCodeRulesEntity.class, query);
        rulesEntity.setVersion(version);
        return codeRulesManager.updateById(rulesEntity);
    }


    /**
     * 删除规则
     *
     * @param id
     * @return
     */
    @Override
    public boolean deleteCodeRulers(Long id) {
        return codeRulesManager.removeById(id);
    }

    /**
     * 分页查询
     *
     * @param query
     * @return
     */
    @Override
    public PageInfo<TsCodeRulesEntity> listCodeRulers(CodeRulesListQuery query) {
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        return PageInfo.of(codeRulesManager.listCodeRules(query));
    }

    /**
     * 获取详情
     *
     * @param id
     * @return
     */
    @Override
    public TsCodeRulesEntity getRulesInfo(Long id) {
        return codeRulesManager.getById(id);
    }


    //############################### 私有函数 ###############################


    /**
     * 修改规则表 version
     *
     * @param rulesEntity
     * @param query
     * @return
     */
    private int updateVersion(TsCodeRulesEntity rulesEntity, CodeRulesUpdateQuery query) {
        if (!StrUtil.equals(rulesEntity.getType().toString(), query.getType().toString())) {
            return rulesEntity.getVersion() + 1;
        } else {
            if (0 == rulesEntity.getType()) {
                //自定义类
                if (!StrUtil.equals(rulesEntity.getClassName(), query.getClassName()) ||
                        !StrUtil.equals(rulesEntity.getParams(), query.getParams())) {
                    return rulesEntity.getVersion() + 1;
                }
            } else {
                //自定义规则
                if (!StrUtil.equals(rulesEntity.getRules(), query.getRules()) ||
                        !StrUtil.equals(rulesEntity.getLength().toString(), query.getLength().toString())) {
                    return rulesEntity.getVersion() + 1;
                }
            }
        }
        return rulesEntity.getVersion();
    }

    /**
     * 校验code是否已经生成编码
     *
     * @param code
     * @return
     */
    private boolean checkIsCreateCode(String code) {
        List<TsCodeRulesDataEntity> list = codeRulesDataManager.getByRulesJsonList(code, null);
        return CollUtil.isNotEmpty(list);
    }

    /**
     * 校验 Code 是否存在
     */
    private <T extends CodeRulesBaseQuery> void validateRulesCode(T query) {
        TsCodeRulesEntity entity = codeRulesManager.getByCode(query.getCode());
        if (query instanceof CodeRulesInsertQuery && null != entity) {
            //页面编码已存在
            Asserts.fail("[ts.code.exist]");
        }
        if (query instanceof CodeRulesUpdateQuery &&
                null != entity &&
                !((CodeRulesUpdateQuery) query).getId().equals(entity.getId())) {
            //页面编码已存在
            Asserts.fail("[ts.code.exist]");
        }

        if (query.getType() == 1) {
            List<CodeRulesDto> rulesDtoList = JSONArray.parseArray(query.getRules(), CodeRulesDto.class);
            long count = rulesDtoList.stream().filter(item -> RulesTypeEnum.SERIAL_NUMBER.getType().equals(item.getType())).count();
            if (count > 1) {
                Asserts.fail("[ts.only.one.serial.number]");
            }
        }
    }


    public String testInitCode(String a, JSONObject b, Integer c) {
        return UUID.randomUUID().toString();
    }

}
